package com.java110.mall.cart.cmd.storeOrderCartReturn;

import com.alibaba.fastjson.JSONObject;
import com.java110.core.annotation.Java110Cmd;
import com.java110.core.annotation.Java110Transactional;
import com.java110.core.context.ICmdDataFlowContext;
import com.java110.core.event.cmd.Cmd;
import com.java110.core.event.cmd.CmdEvent;
import com.java110.core.factory.GenerateCodeFactory;
import com.java110.dto.account.AccountDto;
import com.java110.dto.onlinePay.OnlinePayDto;
import com.java110.dto.storeOrder.RefundOrderDto;
import com.java110.dto.storeOrder.StoreOrderDto;
import com.java110.dto.storeOrder.StoreOrderCartDto;
import com.java110.dto.storeOrder.StoreOrderCartEventDto;
import com.java110.dto.storeOrder.StoreOrderCartReturnDto;
import com.java110.intf.acct.IAccountInnerServiceSMO;
import com.java110.intf.acct.IOnlinePayV1InnerServiceSMO;
import com.java110.intf.acct.IRefundOrderMoneyV1InnerServiceSMO;
import com.java110.intf.cart.*;
import com.java110.intf.goods.IProductSpecValueInnerServiceSMO;
import com.java110.po.account.AccountDetailPo;
import com.java110.po.product.ProductSpecValuePo;
import com.java110.po.storeOrder.StoreOrderPo;
import com.java110.po.storeOrder.StoreOrderCartPo;
import com.java110.po.storeOrder.StoreOrderCartEventPo;
import com.java110.po.storeOrder.StoreOrderCartReturnPo;
import com.java110.po.storeOrder.StoreOrderCartReturnEventPo;
import com.java110.utils.cache.MappingCache;
import com.java110.utils.constant.MappingConstant;
import com.java110.utils.exception.CmdException;
import com.java110.utils.util.Assert;
import com.java110.utils.util.BeanConvertUtil;
import com.java110.utils.util.ListUtil;
import com.java110.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.List;


@Java110Cmd(serviceCode = "storeOrderCartReturn.auditStoreOrderCartReturn")
public class AuditStoreOrderCartReturnCmd extends Cmd {


    @Autowired
    private IStoreOrderCartReturnInnerServiceSMO storeOrderCartReturnInnerServiceSMOImpl;

    @Autowired
    private IStoreOrderCartReturnEventInnerServiceSMO storeOrderCartReturnEventInnerServiceSMOImpl;

    @Autowired
    private IStoreOrderCartEventInnerServiceSMO storeOrderCartEventInnerServiceSMOImpl;

    @Autowired
    private IStoreOrderCartInnerServiceSMO storeOrderCartInnerServiceSMOImpl;

    @Autowired
    private IStoreOrderInnerServiceSMO storeOrderInnerServiceSMOImpl;

    @Autowired
    private IProductSpecValueInnerServiceSMO productSpecValueInnerServiceSMOImpl;

    @Autowired
    private IOnlinePayV1InnerServiceSMO onlinePayV1InnerServiceSMOImpl;

    @Autowired
    private IRefundOrderMoneyV1InnerServiceSMO refundOrderMoneyV1InnerServiceSMOImpl;

    @Autowired
    private IAccountInnerServiceSMO accountInnerServiceSMOImpl;

    private static final String STATE_Y = "1100"; // 同意
    private static final String STATE_N = "1200"; //拒绝

    @Override
    public void validate(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException {
        Assert.hasKeyAndValue(reqJson, "state", "请求报文中未包含审核状态");
        Assert.hasKeyAndValue(reqJson, "message", "请求报文中未包含审核内容");
        Assert.hasKeyAndValue(reqJson, "shopId", "商铺不能为空");

        if (reqJson.containsKey("orderId")) {
            StoreOrderCartReturnDto storeOrderCartReturnDto = new StoreOrderCartReturnDto();
            storeOrderCartReturnDto.setOrderId(reqJson.getString("orderId"));
            storeOrderCartReturnDto.setShopId(reqJson.getString("shopId"));
            List<StoreOrderCartReturnDto> storeOrderCartReturnDtos = storeOrderCartReturnInnerServiceSMOImpl.queryStoreOrderCartReturns(storeOrderCartReturnDto);
            if (ListUtil.isNull(storeOrderCartReturnDtos)) {
                throw new CmdException("没有退单订单");
            }
            reqJson.put("returnId", storeOrderCartReturnDtos.get(0).getReturnId());
        }
        Assert.hasKeyAndValue(reqJson, "returnId", "returnId不能为空");
    }

    @Override
    @Java110Transactional
    public void doCmd(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException {
        StoreOrderCartReturnPo storeOrderCartReturnPo = BeanConvertUtil.covertBean(reqJson, StoreOrderCartReturnPo.class);

        StoreOrderCartReturnDto storeOrderCartReturnDto = new StoreOrderCartReturnDto();
        storeOrderCartReturnDto.setReturnId(storeOrderCartReturnPo.getReturnId());
        storeOrderCartReturnDto.setShopId(storeOrderCartReturnPo.getShopId());
        List<StoreOrderCartReturnDto> storeOrderCartReturnDtos
                = storeOrderCartReturnInnerServiceSMOImpl.queryStoreOrderCartReturns(storeOrderCartReturnDto);
        Assert.listOnlyOne(storeOrderCartReturnDtos, "退货单不存在");

        /**
         * 整单退单逻辑
         */
        if (StoreOrderCartReturnDto.RETURN_TYPE_ORDER.equals(storeOrderCartReturnDtos.get(0).getReturnType())) {
            updateOrderReturn(storeOrderCartReturnPo, storeOrderCartReturnDtos.get(0));
            return;
        }


        StoreOrderCartDto storeOrderCartDto = new StoreOrderCartDto();
        storeOrderCartDto.setCartId(storeOrderCartReturnDtos.get(0).getCartId());
        storeOrderCartDto.setShopId(storeOrderCartReturnPo.getShopId());
        List<StoreOrderCartDto> storeOrderCartDtos
                = storeOrderCartInnerServiceSMOImpl.queryStoreOrderCarts(storeOrderCartDto);
        Assert.listOnlyOne(storeOrderCartDtos, "订单明细不存在");

        String state = storeOrderCartReturnPo.getState();

        if (STATE_Y.equals(state)) {
            storeOrderCartReturnPo.setState(StoreOrderCartReturnDto.STATE_Y);
        } else {
            storeOrderCartReturnPo.setState(StoreOrderCartReturnDto.STATE_N);
        }
        int flag = storeOrderCartReturnInnerServiceSMOImpl.updateStoreOrderCartReturn(storeOrderCartReturnPo);

        if (flag < 1) {
            throw new CmdException("保存失败");
        }

        StoreOrderCartReturnEventPo storeOrderCartReturnEventPo = new StoreOrderCartReturnEventPo();
        storeOrderCartReturnEventPo.setEventId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_eventId));
        storeOrderCartReturnEventPo.setEventMsg(storeOrderCartReturnPo.getMessage());
        storeOrderCartReturnEventPo.setEventObjId(storeOrderCartReturnDtos.get(0).getPersonId());
        storeOrderCartReturnEventPo.setEventObjType("U");//用户申请
        storeOrderCartReturnEventPo.setReturnId(storeOrderCartReturnPo.getReturnId());
        storeOrderCartReturnEventPo.setStoreId(storeOrderCartReturnDtos.get(0).getStoreId());
        storeOrderCartReturnEventPo.setShopId(storeOrderCartReturnPo.getShopId());

        flag = storeOrderCartReturnEventInnerServiceSMOImpl.saveStoreOrderCartReturnEvent(storeOrderCartReturnEventPo);
        if (flag < 1) {
            throw new CmdException("保存失败");
        }


        //加入订单事件
        StoreOrderCartEventPo storeOrderCartEventPo = new StoreOrderCartEventPo();
        storeOrderCartEventPo.setEventId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_eventId));
        storeOrderCartEventPo.setEventMsg(storeOrderCartReturnPo.getMessage());
        storeOrderCartEventPo.setEventObjId(storeOrderCartReturnDtos.get(0).getPersonId());
        storeOrderCartEventPo.setEventObjType("U");//用户申请
        storeOrderCartEventPo.setEventType(StoreOrderCartEventDto.EVENT_TYPE_COMMON);
        storeOrderCartEventPo.setOrderId(storeOrderCartReturnDtos.get(0).getOrderId());
        storeOrderCartEventPo.setCartId(storeOrderCartReturnDtos.get(0).getCartId());
        storeOrderCartEventPo.setShopId(storeOrderCartReturnPo.getShopId());

        flag = storeOrderCartEventInnerServiceSMOImpl.saveStoreOrderCartEvent(storeOrderCartEventPo);
        if (flag < 1) {
            throw new CmdException("保存失败");
        }


        StoreOrderCartPo storeOrderCartPo = new StoreOrderCartPo();
        storeOrderCartPo.setCartId(storeOrderCartReturnDtos.get(0).getCartId());
        if (!STATE_Y.equals(state)) {
            storeOrderCartPo.setState(StoreOrderCartDto.STATE_RETURN_FAIL);
            storeOrderCartPo.setStoreId(storeOrderCartReturnDtos.get(0).getStoreId());
            storeOrderCartPo.setShopId(storeOrderCartReturnPo.getShopId());
            flag = storeOrderCartInnerServiceSMOImpl.updateStoreOrderCart(storeOrderCartPo);
            if (flag < 1) {
                throw new CmdException("保存失败");
            }
            return;
        }

        storeOrderCartPo.setState(StoreOrderCartDto.STATE_RETURN_SUCCESS);
        //减去销售 数量和金额
        BigDecimal cartNum = new BigDecimal(storeOrderCartDtos.get(0).getCartNum());
        BigDecimal payPrice = new BigDecimal(storeOrderCartDtos.get(0).getPayPrice());
        cartNum = cartNum.subtract(new BigDecimal(storeOrderCartReturnDtos.get(0).getReturnCartNum())).setScale(2, BigDecimal.ROUND_HALF_UP);
        payPrice = payPrice.subtract(new BigDecimal(storeOrderCartReturnDtos.get(0).getReturnPayPrice())).setScale(2, BigDecimal.ROUND_HALF_UP);
        storeOrderCartPo.setCartNum(cartNum.doubleValue() + "");
        storeOrderCartPo.setPayPrice(payPrice.doubleValue() + "");

        storeOrderCartPo.setStoreId(storeOrderCartReturnDtos.get(0).getStoreId());
        storeOrderCartPo.setShopId(storeOrderCartReturnPo.getShopId());
        flag = storeOrderCartInnerServiceSMOImpl.updateStoreOrderCart(storeOrderCartPo);
        if (flag < 1) {
            throw new CmdException("保存失败");
        }

        //更新库存中数量
        ProductSpecValuePo productSpecValuePo = new ProductSpecValuePo();
        productSpecValuePo.setStoreId(storeOrderCartReturnDtos.get(0).getStoreId());
        productSpecValuePo.setProductId(storeOrderCartDtos.get(0).getProductId());
        productSpecValuePo.setValueId(storeOrderCartDtos.get(0).getValueId());
        productSpecValuePo.setAddStock(storeOrderCartReturnDtos.get(0).getReturnCartNum());
        flag = productSpecValueInnerServiceSMOImpl.updateProductSpecValue(productSpecValuePo);
        if (flag < 1) {
            throw new CmdException("保存失败");
        }

        //支付表改为退费状态
        doUpdateOnlinePay(storeOrderCartDtos.get(0).getOrderId(), OnlinePayDto.STATE_WT, "申请退费", storeOrderCartDtos.get(0).getPayPrice());

        // todo 存账户中扣款
        String payPlatform = MappingCache.getValue(MappingConstant.WECHAT_STORE_DOMAIN, "PAY_PLATFORM");
        if ("ON".equals(payPlatform)) {
            returnMoneyFromShopAccount(storeOrderCartDtos.get(0));
        }
        cmdDataFlowContext.setResponseEntity(ResultVo.createResponseEntity(ResultVo.CODE_OK, "保存成功"));
    }

    private void returnMoneyFromShopAccount(StoreOrderCartDto storeOrderCartDto) {
        AccountDto accountDto = new AccountDto();
        accountDto.setObjId(storeOrderCartDto.getShopId());
        accountDto.setAcctType(AccountDto.ACCT_TYPE_CASH);
        List<AccountDto> accountDtos = accountInnerServiceSMOImpl.queryAccounts(accountDto);
        Assert.listOnlyOne(accountDtos, "账户不存在");

        AccountDetailPo accountDetailPo = new AccountDetailPo();
        accountDetailPo.setAcctId(accountDtos.get(0).getAcctId());
        accountDetailPo.setObjId(storeOrderCartDto.getShopId());
        accountDetailPo.setAmount(storeOrderCartDto.getPayPrice());
        accountDetailPo.setRemark("商品退款金额：" + storeOrderCartDto.getCartId());
        accountDetailPo.setObjType(accountDtos.get(0).getObjType());
        accountInnerServiceSMOImpl.withholdAccount(accountDetailPo);
    }


    private void doUpdateOnlinePay(String orderId, String state, String message, String money) {
        //todo 触发支付平台退款逻辑
        refundOrderMoneyV1InnerServiceSMOImpl.refundOrderMoney(new RefundOrderDto(orderId,Double.parseDouble(money)));
    }

    private void updateOrderReturn(StoreOrderCartReturnPo storeOrderCartReturnPo, StoreOrderCartReturnDto storeOrderCartReturnDto) {

        String state = storeOrderCartReturnPo.getState();

        if (STATE_Y.equals(state)) {
            storeOrderCartReturnPo.setState(StoreOrderCartReturnDto.STATE_Y);
        } else {
            storeOrderCartReturnPo.setState(StoreOrderCartReturnDto.STATE_N);
        }
        int flag = storeOrderCartReturnInnerServiceSMOImpl.updateStoreOrderCartReturn(storeOrderCartReturnPo);

        if (flag < 1) {
            throw new CmdException("保存失败");

        }

        StoreOrderCartReturnEventPo storeOrderCartReturnEventPo = new StoreOrderCartReturnEventPo();
        storeOrderCartReturnEventPo.setEventId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_eventId));
        storeOrderCartReturnEventPo.setEventMsg(storeOrderCartReturnPo.getMessage());
        storeOrderCartReturnEventPo.setEventObjId(storeOrderCartReturnDto.getPersonId());
        storeOrderCartReturnEventPo.setEventObjType("U");//用户申请
        storeOrderCartReturnEventPo.setReturnId(storeOrderCartReturnPo.getReturnId());
        storeOrderCartReturnEventPo.setStoreId(storeOrderCartReturnDto.getStoreId());
        storeOrderCartReturnEventPo.setShopId(storeOrderCartReturnPo.getShopId());

        flag = storeOrderCartReturnEventInnerServiceSMOImpl.saveStoreOrderCartReturnEvent(storeOrderCartReturnEventPo);
        if (flag < 1) {
            throw new CmdException("保存失败");
        }


        StoreOrderCartPo storeOrderCartPo = new StoreOrderCartPo();
        storeOrderCartPo.setOrderId(storeOrderCartReturnDto.getOrderId());
        //todo 审核失败
        if (!STATE_Y.equals(state)) {
            storeOrderCartPo.setState(StoreOrderCartDto.STATE_RETURN_FAIL);
            storeOrderCartPo.setStoreId(storeOrderCartReturnDto.getStoreId());
            storeOrderCartPo.setShopId(storeOrderCartReturnPo.getShopId());
            flag = storeOrderCartInnerServiceSMOImpl.updateStoreOrderCart(storeOrderCartPo);
            if (flag < 1) {
                throw new CmdException("保存失败");
            }
            return;
        }
        storeOrderCartPo.setState(StoreOrderCartDto.STATE_RETURN_SUCCESS);
        //减去销售 数量和金额
        storeOrderCartPo.setCartNum("0");
        storeOrderCartPo.setPayPrice("0");

        //查询
        StoreOrderCartDto storeOrderCartDto = new StoreOrderCartDto();
        storeOrderCartDto.setOrderId(storeOrderCartReturnDto.getOrderId());
        List<StoreOrderCartDto> storeOrderCartDtos = storeOrderCartInnerServiceSMOImpl.queryStoreOrderCarts(storeOrderCartDto);
        String payPlatform = MappingCache.getValue(MappingConstant.WECHAT_STORE_DOMAIN, "PAY_PLATFORM");

        for (StoreOrderCartDto tmpStoreOrderCartDto : storeOrderCartDtos) {
            //更新库存中数量
            ProductSpecValuePo productSpecValuePo = new ProductSpecValuePo();
            productSpecValuePo.setStoreId(tmpStoreOrderCartDto.getStoreId());
            productSpecValuePo.setProductId(tmpStoreOrderCartDto.getProductId());
            productSpecValuePo.setValueId(tmpStoreOrderCartDto.getValueId());
            productSpecValuePo.setAddStock(tmpStoreOrderCartDto.getCartNum());
            flag = productSpecValueInnerServiceSMOImpl.updateProductSpecValue(productSpecValuePo);
            if (flag < 1) {
                throw new CmdException("保存失败");
            }

            if ("ON".equals(payPlatform)) {
                returnMoneyFromShopAccount(storeOrderCartDtos.get(0));
            }
        }

        OnlinePayDto onlinePayDto = new OnlinePayDto();
        onlinePayDto.setOrderId(storeOrderCartReturnDto.getOrderId());
        List<OnlinePayDto> onlinePayDtos = onlinePayV1InnerServiceSMOImpl.queryOnlinePays(onlinePayDto);
        if (ListUtil.isNull(onlinePayDtos)) {
            return;
        }
        //支付表改为退费状态
        doUpdateOnlinePay(storeOrderCartDtos.get(0).getOrderId(), OnlinePayDto.STATE_WT, "申请退费", onlinePayDtos.get(0).getTotalFee());
        storeOrderCartPo.setStoreId(storeOrderCartReturnDto.getStoreId());
        storeOrderCartPo.setShopId(storeOrderCartReturnPo.getShopId());
        flag = storeOrderCartInnerServiceSMOImpl.updateStoreOrderCart(storeOrderCartPo);
        if (flag < 1) {
            throw new CmdException("保存失败");
        }

        StoreOrderPo storeOrderPo = new StoreOrderPo();
        storeOrderPo.setOrderId(storeOrderCartReturnDto.getOrderId());
        storeOrderPo.setState(StoreOrderDto.STATE_RETURN_SUCCESS);
        flag = storeOrderInnerServiceSMOImpl.updateStoreOrder(storeOrderPo);
        if (flag < 1) {
            throw new CmdException("退货失败");
        }
    }
}
